/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package neuronalenetzeelearning.model;

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import neuronalenetzeelearning.exceptions.DimensionException;
import neuronalenetzeelearning.view.controlpanel.GraphTestEditor;
import neuronalenetzeelearning.view.gui.Controller;
import neuronalenetzeelearning.view.gui.GUI;
import neuronalenetzeelearning.view.prefuseTest.GraphEditor;

/**
 *
 * @author maria
 */
public class Main {

    public static String vectorToString(Vector<?> vector) {
        StringBuffer str = new StringBuffer();
        if (vector != null) {
            for (int i = 0; i < vector.size(); i++) {
                str.append(vector.get(i).toString() + ", ");
            }
        }
        return str.toString();
    }

    public static void main(final String[] args) {

//------Erzeuge Graphen-----------------------------------------------------INIT
        final Graph graph = new Graph();
        
        //  Erzeuge Nodes & Edges
        Node knoten1 = new Layer1Node("K1");
        Node knoten2 = new Layer1Node("K2");
        Node knoten3 = new Layer2Node("K3");
        Node knoten4 = new Layer2Node("K4");
        Node knoten5 = new Layer1Node("K5");

        double gewicht = 0.2;
        Edge kante1zu3 = new Edge(knoten1, knoten3, gewicht);
        Edge kante1zu4 = new Edge(knoten1, knoten4, -2);
        Edge kante2zu4 = new Edge(knoten2, knoten4, -0.2);
        Edge kante5zu3 = new Edge(knoten5, knoten3, gewicht);
        Edge kante5zu4 = new Edge(knoten5, knoten4, -4);
//        Edge kanteZu1 = new Edge(knoten1, -2);
//        Edge kanteZu2 = new Edge(knoten2, 1);
//        Edge kanteZu5 = new Edge(knoten5, 0);

        knoten1.setInputValue(2);
        knoten2.setInputValue(10);
        knoten5.setInputValue(1);

        knoten1.setThreshold(0.5);
        knoten2.setThreshold(0.02);
        knoten3.setThreshold(0.1);
        knoten4.setThreshold(0.3);
        knoten5.setThreshold(0.8);

//--------------------------------------------------test nettoInput for Knoten4:
        //double net4 = knoten4.nettoinput();
        //System.out.println("NettoInput fuer Knoten4: " + net4);

        //  add edges to graph
        graph.addEdge(kante2zu4);
        graph.addEdge(kante1zu3);
        graph.addEdge(kante1zu4);
        graph.addEdge(kante5zu3);
        graph.addEdge(kante5zu4);

        graph.addNode(knoten1);
        graph.addNode(knoten2);
        graph.addNode(knoten3);
        graph.addNode(knoten4);
        graph.addNode(knoten5);

//  -------------------------------------------------------delete node and edge:
        //graph.deleteNode(knoten5);
        //graph.deleteEdge(kante1zu4);

       System.out.println("Adjazenzmatrix vom Graph \n" + graph.getWeightMatrix());


// -----------------------------------------------------supervised Learningrule:
        
/*      Vector<Vector<Double>>Eingaben = new Vector<Vector<Double>>();
        Vector<Double> ersteEingabe = new Vector<Double>();
        ersteEingabe.add(1.); ersteEingabe.add(0.); ersteEingabe.add(0.);
        Eingaben.add(ersteEingabe);
        Vector<Double> zweiteEingabe = new Vector<Double>();
        zweiteEingabe.add(0.); zweiteEingabe.add(1.); zweiteEingabe.add(1.);
        Eingaben.add(zweiteEingabe);


        Vector<Vector<Double>>Ausgaben = new Vector<Vector<Double>>();
        Vector<Double> ersteAusgabe = new Vector<Double>();
        ersteAusgabe.add(1.); ersteAusgabe.add(0.);
        Ausgaben.add(ersteAusgabe);
        Vector<Double> zweiteAusgabe = new Vector<Double>();
        zweiteAusgabe.add(0.); zweiteAusgabe.add(1.);
        Ausgaben.add(zweiteAusgabe);

        double Lernrate = 0.3;
         
        SupervisedLearningRule delta = new SupervisedLearningRule(graph, Eingaben, Ausgaben, Lernrate, StepFunction.LINEAR);
        delta.nextStep();
        System.out.println("Input: {1,0,1}; Lernziel: {1,1};");
        for(int i=1; i<=1000; i++){
           delta.nextStep();
           System.out.println(i+".Lernschritt(überwacht) \n" + graph.getWeightMatrix());
        }*/
        //delta.UnRestrictedLearningIteration();

        
        //----------------------------------------------------Teste stepfuction:
        /*Vector<Double> eingabe = new Vector<Double>();
        eingabe.add(4.0);
        eingabe.add(3.0);
        eingabe.add(-6.0);
        try {
            graph.setInputVector(eingabe);
        } catch (DimensionException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        for (int i = 0; i < 5; i++) {
            System.out.println("Ausgangswert K" + i + " " + graph.getNodes().get(i).getOutputValue());
            System.out.println("Nettoinput von K" + i + ": " + graph.getNodes().get(i).nettoinput());
        }*/

//-------------------------------------------------------------------Tetse Hebb:
        //Eingabemuster.add(e);
//        double lernr = 0.05;
//        HebbLearningRule hebbLearningRuleHeav = new HebbLearningRule (graph,0.05,StepFunction.HEAVISIDE);
//        hebbLearningRuleHeav.nextStep();
//        for (int i=0;i<3;i++){
//             hebbLearningRuleHeav.getChangeWeight(graph);
//            // System.out.println(i+ ": nicht überwacht \n" + graph.getMatrix());
//             System.out.println(i+ ": n_ü Heavi \n" + graph.getWeightMatrix());
//        }

//        HebbLearningRule hebbLearningRuleLin = new HebbLearningRule (graph,0.05,StepFunction.LINEAR);
//        hebbLearningRuleLin.nextStep();
//        for (int i=0;i<3;i++){
//             hebbLearningRuleLin.getChangeWeight(graph);
//            // System.out.println(i+ ": nicht überwacht \n" + graph.getMatrix());
//             System.out.println(i+ ": n_ü Lin \n" + graph.getWeightMatrix());
//        }
//
        //HebbLearningRule hebbLearningRuleSig = new HebbLearningRule(graph, 0.05, StepFunction.SIGMOID);
       // hebbLearningRuleSig.nextStep();
        /*for (int i = 0; i < 50; i++) {
            hebbLearningRuleSig.nextStep();
            // System.out.println(i+ ": nicht überwacht \n" + graph.getMatrix());
            System.out.println(i + ": n_ü Sig \n" + graph.getWeightMatrix());
        }*/

       //hebbLearningRuleSig.UnRestrictedLearningIteration();
        
        
        //Converting the graph to GraphML (XML for graphs) [WORKS!]
//        System.out.println("GraphML-Dokument:\n" + GraphMLDocumentBuilder.convertToGraphMLAsString(graph));

        //Create GUI and run it in a Event-Dispatcher


        Runnable r = new Runnable() {

            @Override
            public void run() {
                //new GraphEditor(graph);
                new GraphTestEditor(graph.getExampleGraph());
            }
        };
        SwingUtilities.invokeLater(r);

/**
        Vector<Edge> alleKanten_K3 = knoten3.getEdges();
        System.out.println("alle Kanten: " + vectorToString(alleKanten_K3));
        Vector<Edge> eingehKanten_K3 = knoten3.getIncomingEdges();
        System.out.println("eingehende Kanten: " + vectorToString(eingehKanten_K3));
        Vector<Edge> ausgehKanten_K3 = knoten3.getOutgoingEdges();
        System.out.println("alle Kanten: " + vectorToString(ausgehKanten_K3));

        int anzKanten = alleKanten_K3.size();
        System.out.println("Knoten 3 besitzt insgesamt " + anzKanten + " Kanten;");

        anzKanten = eingehKanten_K3.size();
        System.out.println("davon sind insgesamt " + anzKanten + " eingehende Kanten;");
*/
        
    }
}
